package de.rts.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import java.util.Set;

import de.rts.components.Train;

public class TimeLine extends BufferedImage
{
  private static Font tickLabelFont   = new Font("Courier New", Font.ITALIC, 9);
  private static Font axisLabelFont   = new Font("SansSerif", Font.ITALIC, 12);
  private Set<Train>  trains;
  private int         deadlineLabel   = 35;
  private Point[]     timeShift       = new Point[2];
  private boolean     iceArrived      = false;
  private Point[]     iceMarker       = null;
  private boolean     regionalArrived = false;
  private Point[]     regionalMarker  = null;
  private boolean     cargoArrived    = false;
  private Point[]     cargoMarker     = null;

  public TimeLine(int width, int height, int imageType)
  {
    super(width, height, imageType);
    timeShift[0] = new Point(0, 60);
    timeShift[1] = new Point(0, 90);
  }

  protected void drawTimeLine()
  {
    int x1 = 0, y1 = 60, x2 = 0, y2 = 90;
    Graphics g = getGraphics();
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.BLACK);
    g.drawLine(0, 90, 915, 90); // horizontal time line
    g.drawLine(x1, y1, x2, y2); // beginning vertical line

    for (int i = 1; i < 61 * 5; i++)
    {
      if (i % 5 == 0 && i != 0)
      {
        g.drawLine(x1 += 3, y1 + 4, x2 += 3, y2); // 5 ticks vertical line
        g.setFont(tickLabelFont);
        g.drawString(String.valueOf(i / 5), x2 - 4, y2 + 13);
      }
      else
      {
        if (x1 < 935) g.drawLine(x1 += 3, y1 + 10, x2 += 3, y2);
      }
    }

    g.drawLine(915, 60, 915, 90);// ending vertical line
    g.setFont(axisLabelFont);
    g.drawString("time[s]", 925, 90);
    Util.drawThickLine(g, timeShift[0].x, timeShift[0].y, timeShift[1].x, timeShift[1].y, 2,
      Util.setHSBColor(0, 99, 88));
    if (trains != null)
    {
      Iterator<Train> iter = this.trains.iterator();
      while (iter.hasNext())
      {
        Train train = iter.next();
        drawDeadlines(train.getName(), train.getDeadline());
      }
    }

    if (iceArrived)
    {
      if (iceMarker == null) iceMarker = getCurrentShiftPosition();
      Util.drawThickLine(getGraphics(), iceMarker[0].x, iceMarker[0].y, iceMarker[1].x, iceMarker[1].y, 2,
        Util.setHSBColor(0, 0, 0));
    }

    if (regionalArrived)
    {
      if (regionalMarker == null) regionalMarker = getCurrentShiftPosition();
      Util.drawThickLine(getGraphics(), regionalMarker[0].x, regionalMarker[0].y, regionalMarker[1].x,
        regionalMarker[1].y, 2, Util.setHSBColor(262, 13, 38));
    }

    if (cargoArrived)
    {
      if (cargoMarker == null) cargoMarker = getCurrentShiftPosition();
      Util.drawThickLine(getGraphics(), cargoMarker[0].x, cargoMarker[0].y, cargoMarker[1].x, cargoMarker[1].y, 2,
        Util.setHSBColor(180, 43, 59));
    }
  }

  public void setTimeShiftOffset(int offset)
  {
    for (Point p : timeShift)
      p.x = offset;
  }

  private void drawDeadlines(String s, int x)
  {
    final int y = 60;
    Graphics g = getGraphics();
    x *= 5 * 3;
    g.setColor(Color.red);
    g.drawLine(x, y, x - 5, y - 10);
    g.drawLine(x, y, x - 10, y - 5);
    g.drawLine(x - 10, y - 5, x - 5, y - 10);
    g.drawLine(x, y, x - 20, y - 20);
    g.drawLine(x - 20, y - 20, x, y - 15);
    g.drawLine(x, y - 15, x - 20, y - 35);
    g.drawString(s, x - 35, y - 35);
  }

  public void setICEMarker()
  {
    iceArrived = true;
  }

  public void setRegionalMarker()
  {
    regionalArrived = true;
  }

  public void setCargoMarker()
  {
    cargoArrived = true;
  }

  public Set<Train> getTrains()
  {
    return trains;
  }

  public void setTrains(Set<Train> trains)
  {
    this.trains = trains;
  }

  private Point[] getCurrentShiftPosition()
  {
    Point[] temp = new Point[]
    { new Point(), new Point() };
    temp[0].x = timeShift[0].x;
    temp[0].y = timeShift[0].y;
    temp[1].x = timeShift[1].x;
    temp[1].y = timeShift[1].y;
    return temp;
  }
}
